#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/7/11 11:00
# @Author  : CoderCharm
# @File    : role.py
# @Software: PyCharm
# @Desc    :
"""
角色表crud操作
"""

from typing import List, Optional
from sqlalchemy.orm import Session
from sqlalchemy import func, or_

from api.common.curd_base import CRUDBase
from api.models.auth import Resource,RoleResource
from api.models.auth import Role
from ..schemas import role_schema


class CRUDResource(CRUDBase[Resource,None,None]):

    # def create(self, db: Session, *, obj_in: role_schema.RoleCreate) -> Resource:
    #     db_obj = Role(
    #         name=obj_in.name,
    #         pid=obj_in.pid
    #     )
    #     db.add(db_obj)
    #     db.commit()
    #     db.refresh(db_obj)
    #     return db_obj

    #分页查询所有{"total":100,'list':reslit}
    @staticmethod
    def querytwo_resource(db: Session) -> dict:
        res = db.query(Resource).filter(Resource.pid !=0).all()
        result = [{"key":i.id,"label":i.name,"pid":i.pid} for i in res]
        return {
            "items": result
        }
    @staticmethod
    def del_resource(db: Session,*,ids:List) -> dict:
        res = db.query(RoleResource).filter(RoleResource.roleid==13).delete()
        db.commit()

        for i in ids:
            db_obj = RoleResource(
                id=0,
                roleid=14,
                resourceid=i
            )
            db.add(db_obj)
            db.commit()
            db.refresh(db_obj)
        return {
            "status":'ok'
        }
    
    @staticmethod
    def get_roleresource(db: Session,*,roleid:int) -> dict:
        res = db.query(RoleResource).filter(RoleResource.roleid==roleid).all()
        reslist = []
        if res:
           reslist = [i.resourceid for i in res]
        return {
            "items":reslist
        }
    @staticmethod
    def setResource(db: Session,*,roleid:int,idlist:str) -> dict:
        #删除此角色对应的资源
        db.query(RoleResource).filter(RoleResource.roleid == roleid).delete()
        # db.commit()
        #获取页面传入的资源
        idl = idlist.split(",")
     
        #查询此角色是否有继承角色，如果有查询继承角色所对应的资源
        roles = db.query(Role).filter(Role.id==roleid).first()
        if roles.pid >0:
            pidresource = db.query(RoleResource).filter(RoleResource.roleid==roles.pid).all()
            for i in pidresource:
                resid = str(i.resourceid)
                if resid not in idl:
                    idl.append(resid)
        
        #[2,3,5]
        for i in idl:
            #根据i查询互斥表
            sql = "select * from resource_mutex where resourceid1=%d or resourceid2=%d"%(int(i),int(i))
            res = db.execute(sql)
            reslist = []
            for rid in res:
                reslist.append(str(rid.resourceid1))
                reslist.append(str(rid.resourceid2))
          
            interlist = list(set(idl).intersection(set(reslist)))
            
            if len(interlist)>1:
                return False

        for i in idl:
            #用idl和查询的结果取交集
            #如果交集大于1
            db_obj = RoleResource(
                id=0,
                roleid=roleid,
                resourceid=i
            )
            db.add(db_obj)
        #将查询到的资源写入数据库
        db.commit()

        return True
    

    @staticmethod
    def setProResource(db: Session,*,roleid:int,idlist:str) -> dict:
        #idlist 页面不变，资源id,通过id查询二进制值
        #删除此角色对应的资源
        #获取页面传入的资源
        idl = idlist.split(",")
        #定义一个权限值为0
        promition = 0
        for i in idl:
            resource = db.query(Resource).filter(Resource.id == i).first()
            promition = promition | resource.promition
     
        #查询此角色是否有继承角色，如果有查询继承角色所对应的资源
        roles = db.query(Role).filter(Role.id==roleid).first()
        if roles.pid >0:
            #查询父类的权限列表和promition权限 |
            parent = db.query(Role).filter(Role.id==roles.pid).first()
            promition = promition | parent.promition
        sql = "update role set promition=%d where id=%d"%(promition,roleid)
        db.execute(sql)
        db.commit()

        return True
    
curd_resource = CRUDResource(Resource)
